﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using DataCenter.Models;
using System.Text.RegularExpressions;
using System.Reflection;

namespace Client.Panels
{
   public  class GGKLinePanel : ILinePanel<DataCenter.Models.Kline>
    {
        public static string freq { get; private set; }
        public static string adj { get; private set; }
        public static DateTime? start { get; private set; }
        public static DateTime? end { get; private set; }

        int numPerPage;
        int expectPageNum;
        int maBuffer = 30;
        int viewType = 2;  //0普通视图，1自选视图，2K线视图
        bool quickBeepType = true;//按快捷键获取指定数据时，true 播放beep，false读出数据
        Dictionary<string, YYBeep.Beep[]> lineMap = new System.Collections.Generic.Dictionary<string, YYBeep.Beep[]>();

        int kModelLength { get => Managers.Manager.beepM.kModelWav; }
        int kModelEmptyLength { get => Managers.Manager.beepM.kModelWavEmpty; }
        int zxLength { get => Managers.Manager.beepM.kZXModelWav; }
        int zxEmptyLength { get => Managers.Manager.beepM.kZXModelWavEmpty; }
        int normalLength { get => Managers.Manager.beepM.kNormalWav; }
        int normalEmptyLength { get => Managers.Manager.beepM.kNormalWavEmpty; }

        public GGKLinePanel(IInfo ggInfo, string freq, string adj = "bfq", DateTime? start = null, DateTime? end = null) : base(ggInfo, "")
        {
            GGKLinePanel.freq = freq;
            GGKLinePanel.adj = adj;
            GGKLinePanel.start = start;
            GGKLinePanel.end = end;

            string tmp;
            if (!Managers.Manager.settingM.generalSetting.TryGetValue("expectNumPerPage", out tmp))
                tmp = "70";
            expectPageNum = int.Parse(tmp);
            RegisterHotkey(panelName);

            string clientText = Managers.Manager.jargonM.GetJargon(freq) + " - " + ggInfo.name;
            if (freq.IndexOf('m') == -1 || freq == "month")
            {
                if (adj == "hfq")
                    clientText += " - 后复权";
                else if(adj=="qfq")
                    clientText += " - 前复权";
            }
            this.clientText = clientText;
        }


        protected override async Task<int> InitLines()
        {
            if (start == null|| end == null)
            {
                try
                {
                    data = await DataCenter.DataCenter.GetKline(ggInfo.symbol, freq, adj);
                }
                catch (DataCenter.MyException.APIReturnException e)
                {
                    var l = e.Message.Split('~');
                    if (l[0] == "1000")
                        Utility.ShowLoginAgain();
                    throw;
                }
                if (data.Length >= expectPageNum)
                    numPerPage = expectPageNum;
                else
                    numPerPage = data.Length;
            }
            else
            {
                DateTime tmp;
                switch (freq)
                {
                    case "day":
                        tmp = ((DateTime)start).AddDays(-maBuffer - 10);
                        break;
                    case "week":
                        tmp = ((DateTime)start).AddMonths(-(int)(Math.Ceiling((double)(maBuffer/4)))-1);
                        break;
                    case "month":
                        tmp = ((DateTime) start).AddMonths(-maBuffer);
                        break;
                    case "year":
                        tmp = ((DateTime)start).AddYears(-maBuffer);
                        break;
                    case "m5":
                        tmp = ((DateTime)start).AddDays(-1);
                        break;
                    default:
                        tmp = ((DateTime)start).AddDays(-(maBuffer/2));
                        break;

                }

                try
                {
                    data = await DataCenter.DataCenter.GetKline(ggInfo.symbol, freq, adj, tmp.ToString("yyyy-MM-dd"), ((DateTime)end).ToString("yyyy-MM-dd"));
                    if (data.Length == 0)
                        return -1;
                    int i = 0;
                    while (data[i].time < start) i++;
                    numPerPage = data.Length - i;
                }
                catch (DataCenter.MyException.APIReturnException e)
                {
                    var l = e.Message.Split('~');
                    if (l[0] == "1000")
                        Utility.ShowLoginAgain();
                    throw;
                }
            }
            

            var highLine = new YYBeep.Beep[numPerPage];
            var lowLine = new YYBeep.Beep[numPerPage];
            var openLine = new YYBeep.Beep[numPerPage];
            var closeLine = new YYBeep.Beep[numPerPage];
            var bodyHighLine = new YYBeep.Beep[numPerPage];
            var bodyLowLine = new YYBeep.Beep[numPerPage];
            var ma5Line = new YYBeep.Beep[numPerPage];
            var ma10Line = new YYBeep.Beep[numPerPage];
            var ma20Line = new YYBeep.Beep[numPerPage];
            var ma30Line = new YYBeep.Beep[numPerPage];
            var volLine = new YYBeep.Beep[numPerPage];

            //获取最大值
            float maxVol = 0;
            float max = int.MinValue;
            float min = int.MaxValue;
            for (var i =0;i<data.Length;i++)
            {
                //ma
                if (i >= 4)
                {
                    float temp = 0;
                    for (int j = 0; j < 5; j++)
                    {
                        temp += data[i - j].close;
                    }
                    data[i].ma5 = temp / 5;
                }
                if (i >= 9)
                {
                    float temp = 0;
                    for (int j = 0; j < 10; j++)
                    {
                        temp += data[i - j].close;
                    }
                    data[i].ma10 = temp / 10;
                }
                if (i >= 19)
                {
                    float temp = 0;
                    for (int j = 0; j < 20; j++)
                    {
                        temp += data[i - j].close;
                    }
                    data[i].ma20 = temp / 20;
                }
                if (i >= 29)
                {
                    float temp = 0;
                    for (int j = 0; j < 30; j++)
                    {
                        temp += data[i - j].close;
                    }
                    data[i].ma30 = temp / 30;

                    
                }

                if (i >= data.Length - numPerPage)
                {
                    //寻找最大成交量
                    if (data[i].vol > maxVol)
                        maxVol = data[i].vol;

                    //bodyHigh与bodyLow
                    if (data[i].open > data[i].close)
                    {
                        data[i].bodyHigh = data[i].open;
                        data[i].bodyLow = data[i].close;
                    }
                    else
                    {
                        data[i].bodyHigh = data[i].close;
                        data[i].bodyLow = data[i].open;
                    }

                    //最大值与最小值
                    float temp;
                    temp = ExtremeValue(true, data[i].high, data[i].ma5, data[i].ma10, data[i].ma20, data[i].ma30);
                    if (max < temp)
                        max = temp;
                    temp = ExtremeValue(false, data[i].low, data[i].ma5, data[i].ma10, data[i].ma20, data[i].ma30);
                    if (min > temp)
                        min = temp;
                }
            }
            
            float factor = (max - min) / min / 200;
            for (int i = data.Length-numPerPage; i < data.Length; i++)
            {
                int j = i - (data.Length - numPerPage);

                float pan = -100 + j * (200.0f / numPerPage);
                var volVolume = data[i].vol / maxVol;
                highLine[j] = YYBeep.Beep.CreateBeep((data[i].high - min) / min / factor - 100, pan, 1, Math.Sin, Managers.Manager.beepM.generalWav);
                openLine[j] = YYBeep.Beep.CreateBeep((data[i].open - min) / min / factor - 100, pan, 1, Math.Sin, Managers.Manager.beepM.generalWav);
                lowLine[j] = YYBeep.Beep.CreateBeep((data[i].low - min) / min / factor - 100, pan, 1, Math.Sin, Managers.Manager.beepM.generalWav);
                closeLine[j] = YYBeep.Beep.CreateBeep((data[i].close - min) / min / factor - 100, pan, 1, Math.Sin, Managers.Manager.beepM.generalWav);
                bodyHighLine[j] = YYBeep.Beep.CreateBeep((data[i].bodyHigh - min) / min / factor - 100, pan, 1, Math.Sin, Managers.Manager.beepM.generalWav);
                bodyLowLine[j] = YYBeep.Beep.CreateBeep((data[i].bodyLow - min) / min / factor - 100, pan, 1, Math.Sin, Managers.Manager.beepM.generalWav);
                ma5Line[j] = YYBeep.Beep.CreateBeep((data[i].ma5 - min) / min / factor - 100, pan, 1, Math.Sin, Managers.Manager.beepM.generalWav);
                ma10Line[j] = YYBeep.Beep.CreateBeep((data[i].ma10 - min) / min / factor - 100, pan, 1, Math.Sin, Managers.Manager.beepM.generalWav);
                ma20Line[j] = YYBeep.Beep.CreateBeep((data[i].ma20 - min) / min / factor - 100, pan, 1, Math.Sin, Managers.Manager.beepM.generalWav);
                ma30Line[j] = YYBeep.Beep.CreateBeep((data[i].ma30 - min) / min / factor - 100, pan, 1, Math.Sin, Managers.Manager.beepM.generalWav);
                volLine[j] = YYBeep.Beep.CreateBeep(256, pan, data[i].vol/maxVol, YYBeep.MyMath.SquareWav, Managers.Manager.beepM.generalWav);
            }
            lineMap["high"] = highLine;
            lineMap["open"] = openLine;
            lineMap["close"] = closeLine;
            lineMap["low"] = lowLine;
            lineMap["bodyHigh"] = bodyHighLine;
            lineMap["bodyLow"] = bodyLowLine;
            lineMap["ma5"] = ma5Line;
            lineMap["ma10"] = ma10Line;
            lineMap["ma20"] = ma20Line;
            lineMap["ma30"] = ma30Line;
            lineMap["vol"] = volLine;
            foreach(string i in Managers.Manager.jargonM.GetPanelColumns(panelName))
            {
                if (lineMap.ContainsKey(i))
                    lines.Add(lineMap[i]);
            }

            var r = new DataCenter.Models.Kline[numPerPage];
            Array.Copy(data, data.Length - numPerPage, r, 0, numPerPage);
            data = r;

            return 0;
        }

        public override void Enter()
        {
            if (y < items[y].Count - 1)
                PlayLine(x, lines[y].Length - 1);
            else
                SpeakCell();
        }
        public override void Up()
        {
            y = GetY();
            Navigation(true);
        }
        public override void Down()
        {
            y = GetY(false);
            Navigation(true);
        }
        public override void Left()
        {
            if (viewType == 0)
            {
                beepTime = normalLength;
                beepEmptyTime = normalEmptyLength;
                base.Left();
            }
            else if (viewType == 1)
            {
                beepTime = zxLength; ;
                beepEmptyTime = zxEmptyLength;
                base.Left();
            }
            else
            {
                //x--;
                //LeftAndRight();
                base.Left();
            }
        }
        public override void Right()
        {
            if (viewType < 2)
                base.Right();
            else
            {
                //x++;
                //LeftAndRight();
                base.Right();
            }
        }
        public override void PageUp()
        {
            x -= int.Parse(Managers.Manager.settingM.fsSetting["numPerPage"]);
            Navigation(false);
            SpeakTime();
        }
        public override void PageDown()
        {
            x += int.Parse(Managers.Manager.settingM.fsSetting["numPerPage"]);
            Navigation(false);
            SpeakTime();
        }
        public override void SetEndPoint()
        {
            if (x > -1)
            {
                endPoint = x;
                PlayLine(startPoint, endPoint);
            }
        }

        public void ViewTypeAdd()
        {
            ChangeViewType(viewType+1);
        }
        public void ViewTypeCut()
        {
            ChangeViewType(viewType-1);
        }
        List<int> tempSelect = new System.Collections.Generic.List<int>();
        void ChangeViewType(int value)
        {
            if (value > 2)
                viewType = 0;
            else if (value < 0)
                viewType = 2;
            else
                viewType = value;
            switch (viewType)
            {
                case 0:
                    Managers.Manager.ttsM.Speak("自选模式");
                    break;
                case 1:
                    tempSelect.Clear();
                    for(int i = 0; i < selectedLine.Length; i++)
                    {
                        if (selectedLine[i])
                            tempSelect.Add(i);
                    }
                    Managers.Manager.ttsM.Speak("专注模式");
                    break;
                case 2:
                    Managers.Manager.ttsM.Speak("K线模式");
                    break;
            }
        }

        protected override string timeToText(DateTime time)
        {
            if (Regex.IsMatch(freq, @"m\d"))
                return time.ToString("H点mm分,yyyy年M月d日");
            return base.timeToText(time);
        }

        protected override void SoundFeedback(bool upAndDown)
        {
            if (upAndDown || viewType != 2)
                base.SoundFeedback(upAndDown);
            else
                LeftAndRight();
        }
        void LeftAndRight()
        {
            if (x > -1)
            {
                lineMap["open"][x].time = kModelLength;
                lineMap["close"][x].time = kModelLength;
                lineMap["vol"][x].time = kModelLength;
                lineMap["high"][x].time = kModelLength;
                lineMap["low"][x].time = kModelLength;
                YYBeep.Beep[] bs = new YYBeep.Beep[] { null, YYBeep.Beep.CreateEmptyBeep(kModelEmptyLength), lineMap["open"][x], YYBeep.Beep.CreateEmptyBeep(kModelLength), lineMap["close"][x], YYBeep.Beep.CreateEmptyBeep(kModelLength), null, YYBeep.Beep.CreateEmptyBeep(kModelLength), lineMap["vol"][x] };

                if (data[x].open <= data[x].close)
                {
                    bs[0] = lineMap["low"][x];
                    bs[6] = lineMap["high"][x];
                }
                else
                {
                    bs[0] = lineMap["high"][x];
                    bs[6] = lineMap["low"][x];
                }
                Managers.Manager.beepM.PlayBeeps(bs);

                for(int i = 0; i < bs.Length; i += 2)
                {
                    bs[i].time = Managers.Manager.beepM.generalWav;
                }
            }
        }

        int GetY(bool up=true)
        {
            if (x > -1)
            {
                switch (viewType)
                {
                    case 0:
                        if (up)
                            y -= 1;
                        else
                            y += 1;
                        break;
                    case 1:
                        if (up)
                        {
                            if (y <= selectedLine.Length)
                            {
                                for (int i = tempSelect.Count-1; i >=0; i--)
                                {
                                    if (tempSelect[i]<y)
                                    {
                                        y = tempSelect[i];
                                        break;
                                    }
                                }
                            }
                            else
                                y--;
                        }
                        else
                        {
                            bool temp = false;
                            for(int i = 0; i < tempSelect.Count; i++)
                            {
                                if (tempSelect[i]>y)
                                {
                                    y = tempSelect[i];
                                    temp = true;
                                    break;
                                }
                            }
                            if (!temp)
                                y = lines.Count;
                        }
                        break;
                    case 2:
                        if (up)
                        {
                            if (y == items[x].Count - 1)
                                y = items[x].Count - 2;
                            else if (y > 3)
                                y = 3;
                            else
                                y--;
                        }
                        else
                        {
                            if (y < 3)
                                y++;
                            else if (y < items[x].Count - 2)
                                y = items[x].Count - 2;
                            else
                                y = items[x].Count - 1;
                        }
                        break;
                }
            }
            return y;
        }

        float ExtremeValue(bool isMax, params float[] values)
        {
            float temp;
            int i = 0;
            while (values[i] == 0) i++;
            temp = values[i];

            foreach(float v in values)
            {
                if (v != 0)
                {
                    if (isMax && temp < v)
                        temp = v;
                    else if (!isMax && temp > v && v!=0)
                        temp = v;
                }
            }
            return temp;
        }

        


        //====================


        public void ChangeQuickBeepType()
        {
            quickBeepType = !quickBeepType;
            if (quickBeepType)
                Managers.Manager.ttsM.Speak("音效");
            else
                Managers.Manager.ttsM.Speak("语音");
        }

        public void SpeakHighest()
        {
            var p = typeof(DataCenter.Models.Kline).GetProperty("high", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
            int index = GetHighestAndLowest<float>(data.Length - numPerPage, data.Length - 1, p, offset: data.Length - numPerPage);
            Managers.Manager.beepM.PlayBeep(lineMap["high"][index]);
            Managers.Manager.ttsM.Speak("视图最高价" + data[index].high.ToString("F2"));
        }
        public void JumpToHighest()
        {
            var p = typeof(DataCenter.Models.Kline).GetProperty("high", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
            int index = GetHighestAndLowest<float>(data.Length - numPerPage, data.Length - 1, p, offset: data.Length - numPerPage);
            x = index - (data.Length - numPerPage);
            Managers.Manager.beepM.PlayBeep(lineMap["high"][index]);
            Managers.Manager.ttsM.Speak("跳转视图最高价");
        }
        public void SpeakLowest()
        {
            var p = typeof(DataCenter.Models.Kline).GetProperty("low", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
            int index = GetHighestAndLowest<float>(data.Length - numPerPage, data.Length - 1, p,false, offset: data.Length - numPerPage);
            Managers.Manager.beepM.PlayBeep(lineMap["low"][index]);
            Managers.Manager.ttsM.Speak("视图最低价" + data[index].low.ToString("F2"));
        }
        public void JumpToLowest()
        {
            var p = typeof(DataCenter.Models.Kline).GetProperty("low", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
            int index = GetHighestAndLowest<float>(data.Length - numPerPage, data.Length - 1, p, false, offset: data.Length - numPerPage);
            x = index + numPerPage - data.Length;
            Managers.Manager.beepM.PlayBeep(lineMap["low"][index]);
            Managers.Manager.ttsM.Speak("跳转视图最低价");
        }
        public void SpeakVolMax()
        {
            var p = typeof(DataCenter.Models.Kline).GetProperty("vol", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
            int index = GetHighestAndLowest<float>(data.Length - numPerPage, data.Length - 1, p, offset: data.Length - numPerPage);
            Managers.Manager.beepM.PlayBeep(lineMap["vol"][index]);
            string str = "";
            if (data[index].vol > 100000000)
                str = (data[index].vol / 100000000).ToString("F2") + "亿";
            else if (data[index].vol > 10000)
                str = (data[index].vol / 10000).ToString("F2") + "万";
            Managers.Manager.ttsM.Speak("最大成交量" + str);
        }
        public void JumpToVolMax()
        {
            var p = typeof(DataCenter.Models.Kline).GetProperty("vol", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
            int index = GetHighestAndLowest<float>(data.Length - numPerPage, data.Length - 1, p, offset: data.Length - numPerPage);
            x = index + numPerPage - data.Length;
            Managers.Manager.beepM.PlayBeep(lineMap["vol"][index]);
            Managers.Manager.ttsM.Speak("跳转最大成交量");
        }

        public void SpeakRangeHighest()
        {
            var p = typeof(DataCenter.Models.Kline).GetProperty("high", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
            int index = GetHighestAndLowest<float>(startPoint, endPoint, p, offset: data.Length - numPerPage);
            Managers.Manager.beepM.PlayBeep(lineMap["high"][index]);
            Managers.Manager.ttsM.Speak("区间最高价" + data[index].high.ToString("F2"));
        }
        public void JumpRangeToHighest()
        {
            var p = typeof(DataCenter.Models.Kline).GetProperty("high", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
            int index = GetHighestAndLowest<float>(startPoint, endPoint, p, offset: data.Length - numPerPage);
            x = index - (data.Length - numPerPage);
            Managers.Manager.beepM.PlayBeep(lineMap["high"][index]);
            Managers.Manager.ttsM.Speak("跳转区间最高点");
        }
        public void SpeakRangeLowest()
        {
            var p = typeof(DataCenter.Models.Kline).GetProperty("low", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
            int index = GetHighestAndLowest<float>(startPoint, endPoint, p, false, offset: data.Length - numPerPage);
            Managers.Manager.beepM.PlayBeep(lineMap["low"][index]);
            Managers.Manager.ttsM.Speak("区间最低价" + data[index].low.ToString("F2"));
        }
        public void JumpRangeToLowest()
        {
            var p = typeof(DataCenter.Models.Kline).GetProperty("low", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
            int index = GetHighestAndLowest<float>(startPoint, endPoint, p, false, offset: data.Length - numPerPage);
            x = index + numPerPage - data.Length;
            Managers.Manager.beepM.PlayBeep(lineMap["low"][index]);
            Managers.Manager.ttsM.Speak("跳转区间最低点");
        }
        public void SpeakRangeVolMax()
        {
            var p = typeof(DataCenter.Models.Kline).GetProperty("vol", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
            int index = GetHighestAndLowest<float>(startPoint, endPoint, p, offset: data.Length - numPerPage);
            Managers.Manager.beepM.PlayBeep(lineMap["vol"][index]);
            string str = "";
            if (data[index].vol > 100000000)
                str = (data[index].vol / 100000000).ToString("F2") + "亿";
            else if (data[index].vol > 10000)
                str = (data[index].vol / 10000).ToString("F2") + "万";
            Managers.Manager.ttsM.Speak("区间最大成交量" + str);
        }
        public void JumpRangeToVolMax()
        {
            var p = typeof(DataCenter.Models.Kline).GetProperty("vol", BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
            int index = GetHighestAndLowest<float>(startPoint, endPoint, p, offset: data.Length - numPerPage);
            x = index + numPerPage - data.Length;
            Managers.Manager.beepM.PlayBeep(lineMap["vol"][index]);
            Managers.Manager.ttsM.Speak("跳转区间最大成交量");
        }


        public override void SpeakChangepercent()
        {
            if (x < 0 || (x == 0 && data.Length == numPerPage))
                return;
            
            int index = data.Length - numPerPage + x;
            float cp = (data[index].close - data[index - 1].close) / data[index - 1].close * 100;
            QuickSpeakData("changepercent", cp.ToString("F2"));
        }
        public override void SpeakAmplitude()
        {
            if (x < 0 || (x == 0 && data.Length == numPerPage))
                return;

            int index = data.Length - numPerPage + x;
            float am = (data[index].high - data[index].low) / data[index - 1].close * 100;
            QuickSpeakData("amplitude", am.ToString("F2"));
        }
        public void SpeakKType()
        {
            if (x > -1)
            {
                int index = data.Length - numPerPage + x;
                string str = "";
                if (data[index].high == data[index].close || data[index].high == data[index].open)
                    str += "光头";
                if (data[index].low == data[index].close || data[index].low == data[index].open)
                    str += "光脚";
                if (data[index].open < data[index].close)
                    Managers.Manager.ttsM.Speak(str + "阳线");
                else if (data[index].open > data[index].close)
                    Managers.Manager.ttsM.Speak(str + "阴线");
                else
                {
                    if (data[index].high == data[index].low)
                        Managers.Manager.ttsM.Speak("一字线");
                    else if (data[index].high == data[index].close)
                        Managers.Manager.ttsM.Speak("T字线");
                    else if (data[index].low == data[index].close)
                        Managers.Manager.ttsM.Speak("倒T线");
                    else
                        Managers.Manager.ttsM.Speak("十字星");
                }
            }
        }
        public override void SpeakHigh()
        {
            if (x > -1)
            {
                int index = data.Length - numPerPage + x;
                if (quickBeepType)
                    QuickBeep("high", index);
                else
                    QuickSpeakData("high", data[index].high.ToString("F2"));
            }
        }
        public override void SpeakOpen()
        {
            if (x > -1)
            {
                int index = data.Length - numPerPage + x;
                if (quickBeepType)
                    QuickBeep("open", index);
                else
                    QuickSpeakData("open", data[index].open.ToString("F2"));
            }
        }
        public override void SpeakLow()
        {
            if (x > -1)
            {
                int index = data.Length - numPerPage + x;
                if (quickBeepType)
                    QuickBeep("low", index);
                else
                    QuickSpeakData("low", data[index].low.ToString("F2"));
            }
        }
        public override void SpeakTrade()
        {
            if (x > -1)
            {
                int index = data.Length - numPerPage + x;
                if (quickBeepType)
                    QuickBeep("close", index);
                else
                    QuickSpeakData("close", data[index].close.ToString("F2"));
            }
        }
        public override void SpeakVol()
        {
            if (x > -1)
            {
                int index = data.Length - numPerPage + x;
                if (quickBeepType)
                    QuickBeep("vol", index);
                else
                    QuickSpeakData("vol", data[index].vol.ToString());
            }
        }
        public void SpeakMa5()
        {
            if (x > -1)
            {
                int index = data.Length - numPerPage + x;
                if (quickBeepType)
                    QuickBeep("ma5", index);
                else
                    QuickSpeakData("ma5", data[index].ma5.ToString("F2"));
            }
        }
        public void SpeakMa10()
        {
            if (x > -1)
            {
                int index = data.Length - numPerPage + x;
                if (quickBeepType)
                    QuickBeep("ma10", index);
                else
                    QuickSpeakData("ma10", data[index].ma10.ToString("F2"));
            }
        }
        public void SpeakMa20()
        {
            if (x > -1)
            {
                int index = data.Length - numPerPage + x;
                if (quickBeepType)
                    QuickBeep("ma20", index);
                else
                    QuickSpeakData("ma20", data[index].ma20.ToString("F2"));
            }
        }
        public void SpeakMa30()
        {
            if (x > -1)
            {
                int index = data.Length - numPerPage + x;
                if (quickBeepType)
                    QuickBeep("ma30", index);
                else
                    QuickSpeakData("ma30", data[index].ma30.ToString("F2"));
            }
        }
        public void SpeakBodyHigh()
        {
            if (x > -1)
            {
                int index = data.Length - numPerPage + x;
                if (quickBeepType)
                    QuickBeep("bodyHigh", index);
                else
                    QuickSpeakData("bodyHigh", data[index].bodyHigh.ToString("F2"));
            }
        }
        public void SpeakBodyLow()
        {
            if (x > -1)
            {
                int index = data.Length - numPerPage + x;
                if (quickBeepType)
                    QuickBeep("bodyLow", index);
                else
                    QuickSpeakData("bodyLow", data[index].bodyLow.ToString("F2"));
            }
        }


        void QuickBeep(string lineName,int index)
        {
            YYBeep.Beep[] bps;
            if(lineMap.TryGetValue(lineName,out bps))
            {
                Managers.Manager.beepM.PlayBeep(bps[index]);
            }
        }
    }
}
